package com.risen.project.excel.handler;

import com.alibaba.excel.metadata.CellData;
import com.risen.project.excel.annotation.ExcelColumn;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 默认的表头校验 被 ExcelColumn 标注的字段必须在表头中存在 如果不存在则说明表头校验失败
 * {@link ExcelColumn}
 */
public class DefaultExcelHeadCheckHandler implements ExcelHeadCheckHandler {

    @Override
    public boolean check(Map<Integer, CellData> headMap, Class<?> tClass) {

        Field[] fields = tClass.getDeclaredFields();

        // 获取需要映射的Java对象上属性上的注解值 根据该值和表头进行匹配 严格来讲 Java对象的属性上被特殊注解标注的要是表头字段的子集
        List<String> excelColumnNames = Arrays.stream(fields).map(e -> {
            ExcelColumn annotation = e.getAnnotation(ExcelColumn.class);
            return annotation == null ? null : annotation.value();
        }).distinct().filter(e -> !ObjectUtils.isEmpty(e)).collect(Collectors.toList());

        List<String> excelColumns = headMap.values().stream().map(CellData::getStringValue).distinct().collect(Collectors.toList());
        // 取表头字段集合与Java对象属性注解值集合的交集 严格来说 如果交集等于 Java对象属性注解值集合的size 则说明 Java对象需要映射的字段在表格中全部存在
        List<String> filter = excelColumns.stream().filter(excelColumnNames::contains).collect(Collectors.toList());

        return excelColumnNames.size() == filter.size();
    }
}
